home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume12 / cnews / part06 < prev    next >
Encoding:
Internet Message Format  |  1987-10-21  |  52.8 KB

  1. Subject:  v12i031:  C News alpha release, Part06/14
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: utzoo!henry (Henry Spencer)
  7. Posting-number: Volume 12, Issue 31
  8. Archive-name: cnews/part06
  9.  
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 6 (of 14)."
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. if test -f 'batch/sendbatches' -a "${1}" != "-c" ; then 
  20.   echo shar: Will not clobber existing file \"'batch/sendbatches'\"
  21. else
  22. echo shar: Extracting \"'batch/sendbatches'\" \(3153 characters\)
  23. sed "s/^X//" >'batch/sendbatches' <<'END_OF_FILE'
  24. X# Master batching control.
  25. XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}
  26. XNEWSCTL=${NEWSCTL-/usr/lib/news}
  27. XNEWSARTS=${NEWSARTS-/usr/spool/news}
  28. XPATH=$NEWSCTL/batch:$NEWSBIN/batch:/bin:/usr/bin ; export PATH
  29. Xorigpath=$PATH
  30. XNEWSUMASK=${NEWSUMASK-002}
  31. Xumask $NEWSUMASK
  32. X
  33. X# Locking.
  34. Xcd $NEWSCTL
  35. Xecho $$ >LOCKbatch$$
  36. Xif ln LOCKbatch$$ LOCKbatch >/dev/null 2>/dev/null
  37. Xthen
  38. X    rm LOCKbatch$$
  39. X    trap "rm -f $NEWSCTL/LOCKbatch ; exit" 0 1 2 3 15
  40. Xelse
  41. X    rm LOCKbatch$$
  42. X    exit 0
  43. Xfi
  44. X
  45. X# Go to the heart of the matter.
  46. Xcd $NEWSCTL/batch
  47. X
  48. X# Determine what systems are being requested, in what order.
  49. Xcase $#
  50. Xin
  51. X    0)
  52. X    ls | sed -n '/^b\./s///p' | sort >/tmp/nb$$sy
  53. X    if test -r sites
  54. X    then
  55. X        egrep -v '^[     ]*(#|$)' sites | awk '{ print $1, NR }' |
  56. X                            sort >/tmp/nb$$o
  57. X        join -a1 -e 9999 -o 1.1 2.2 /tmp/nb$$sy /tmp/nb$$o >/tmp/nb$$t
  58. X        sort +1 -n /tmp/nb$$t | awk '{ print $1 }' >/tmp/nb$$sy
  59. X    fi
  60. X    syses=`cat /tmp/nb$$sy`
  61. X    rm -f /tmp/nb$$sy /tmp/nb$$o /tmp/nb$$t
  62. X    ;;
  63. X
  64. X    *)
  65. X    case "$1"
  66. X    in
  67. X        -c)
  68. X        if test ! -r sites
  69. X        then
  70. X            echo "$0: -c illegal in absence of sites file" >&2
  71. X            exit 2
  72. X        fi
  73. X        shift
  74. X        syses=`for class in $*
  75. X            do
  76. X                egrep -v '^[     ]*(#|$)' sites |
  77. X                    egrep "[,     ]$class(\$|[,     ])" |
  78. X                    awk '{print $1}'
  79. X            done`
  80. X        ;;
  81. X
  82. X        *)
  83. X        syses="$*"
  84. X        ;;
  85. X    esac
  86. X    ;;
  87. Xesac
  88. X
  89. X# Start up logging.
  90. Xmv $NEWSCTL/batchlog.o $NEWSCTL/batchlog.oo
  91. Xmv $NEWSCTL/batchlog $NEWSCTL/batchlog.o
  92. Xdate >$NEWSCTL/batchlog
  93. X
  94. X# Run through them.
  95. Xfor sys in $syses
  96. Xdo
  97. X    # Move into his directory, include it in search path.
  98. X    here=$NEWSCTL/batch/b.$sys
  99. X    if test ! -d $here
  100. X    then
  101. X        echo "$0:  cannot find batch directory for site $sys" >&2
  102. X        continue
  103. X    fi
  104. X    cd $here
  105. X    PATH=$here:$origpath ; export PATH
  106. X    NEWSSITE=$sys ; export NEWSSITE        # For site-specific programs.
  107. X
  108. X    # Is there anything to do?
  109. X    files=`echo togo*`
  110. X    if test "$files" = 'togo*' || test "$files" = "togo" -a ! -s togo
  111. X    then
  112. X        continue            # no
  113. X    fi
  114. X
  115. X    # How many batches should we send?
  116. X    outstand=`queuelen $sys`
  117. X    limit=`queuemax`
  118. X    nbatch=`expr $limit - $outstand`
  119. X    batchsize=`batchsize`
  120. X    roomfor=`roomfor $batchsize`
  121. X    if test " $nbatch" -gt " $roomfor"
  122. X    then
  123. X        nbatch=$roomfor
  124. X    fi
  125. X
  126. X    # If not allowed to send, remember reason.
  127. X    status='batches flowing'
  128. X    if test " $nbatch" -le 0
  129. X    then
  130. X        if test " $roomfor" -le 0
  131. X        then
  132. X            status='disk too full for batching'
  133. X        else
  134. X            status='queue full'
  135. X        fi
  136. X    fi
  137. X
  138. X    # Try sending some.
  139. X    while test " $nbatch" -gt 0
  140. X    do
  141. X        # Does he have batches prepared already?
  142. X        if test "`echo togo.*`" = 'togo.*'
  143. X        then
  144. X            # No -- need some more batches.
  145. X            if test ! -s togo
  146. X            then
  147. X                break        # Nothing left to do.
  148. X            fi
  149. X            batchprep $batchsize
  150. X        fi
  151. X
  152. X        # Send some batches.
  153. X        them=`ls | egrep '^togo\.' | sed "${nbatch}q"`
  154. X        for f in $them
  155. X        do
  156. X            batchmake -d $NEWSARTS $f | batchmunch |
  157. X                            batchxmit $sys
  158. X            rm $f
  159. X        done
  160. X        ndone=`echo $them | wc -w`
  161. X        nbatch=`expr $nbatch - $ndone`
  162. X
  163. X        # Recheck the space -- it can fall for other reasons.
  164. X        roomfor=`roomfor $batchsize`
  165. X        if test " $nbatch" -gt " $roomfor"
  166. X        then
  167. X            nbatch=$roomfor
  168. X        fi
  169. X    done
  170. X
  171. X    # Report status, if appropriate.
  172. X    nart=`cat togo* | wc -l | awk '{print $1}'`
  173. X    if test " $nart" -gt 0
  174. X    then
  175. X        echo "$sys    backlog $nart ($status)" >>$NEWSCTL/batchlog
  176. X    fi
  177. Xdone
  178. END_OF_FILE
  179. if test 3153 -ne `wc -c <'batch/sendbatches'`; then
  180.     echo shar: \"'batch/sendbatches'\" unpacked with wrong size!
  181. fi
  182. # end of 'batch/sendbatches'
  183. fi
  184. if test -f 'expire/expire.1' -a "${1}" != "-c" ; then 
  185.   echo shar: Will not clobber existing file \"'expire/expire.1'\"
  186. else
  187. echo shar: Extracting \"'expire/expire.1'\" \(3912 characters\)
  188. sed "s/^X//" >'expire/expire.1' <<'END_OF_FILE'
  189. X.TH EXPIRE 1M local
  190. X.DA 3 Oct 1987
  191. X.SH NAME
  192. Xexpire \- expire old news
  193. X.SH SYNOPSIS
  194. X.B /usr/lib/newsbin/expire/expire
  195. X[
  196. X.B \-a
  197. Xarchdir
  198. X] [
  199. X.B \-p
  200. X] [
  201. X.B \-o
  202. X]
  203. X[ controlfile ]
  204. X.SH DESCRIPTION
  205. X.I Expire
  206. Xexpires old news, removing it from the current-news directories and
  207. X(if asked to) archiving it elsewhere.
  208. XIt updates news's
  209. X.I history
  210. Xfile to match.
  211. X.I Expire
  212. Xshould be run nightly.
  213. X.PP
  214. X.IR Expire 's
  215. Xoperations are controlled by a control file
  216. X(which can be named or supplied on standard input),
  217. Xwhich is not optional\(emthere is no default behavior.
  218. XEach line of the control file should have four white-space-separated
  219. Xfields, as follows.
  220. X.PP
  221. XThe first field is one or more newsgroups,
  222. Xseparated by commas (no spaces!);
  223. Xpartial specifications are acceptable (e.g. `comp' specifies all groups
  224. Xwith that prefix).
  225. X.PP
  226. XThe second field is one letter, `m', `u', or `x', specifying that the line
  227. Xapplies only to moderated groups, only to unmoderated groups, or to both,
  228. Xrespectively.
  229. X.PP
  230. XThe third field specifies the expiry period in days.
  231. XThe most general form is three numbers separated by dashes.
  232. XThe units are days; decimal fractions are permitted.
  233. XThe first number gives the retention period:
  234. Xhow long must pass after an article's arrival before it is a candidate
  235. Xfor expiry.
  236. XThe third number gives the purge date:
  237. Xhow long must pass after arrival
  238. Xbefore the article will be expired unconditionally.
  239. XThe middle number gives the default expiry date:
  240. Xhow long after an article's arrival it is expired by default.
  241. XAn explicit expiry date in the article will override the default expiry
  242. Xdate but not the retention period or the purge date.
  243. XIf the field contains only two numbers with a dash separating them,
  244. Xthe retention period defaults to 0.
  245. XIf the field contains only a number, the retention period defaults to 0
  246. Xand the purge date defaults to `never'.
  247. X.PP
  248. XThe fourth field is an archiving directory,
  249. Xor `@' which indicates that the default archiving directory (see \fB\-a\fR)
  250. Xshould be used,
  251. Xor `\-' which suppresses archiving.
  252. X.PP
  253. XThe first line of the control file which applies to a given article is
  254. Xused to control its expiry.
  255. XIt is an error for no line to apply;
  256. Xthe last line should be something like `all\ x\ 14\ \-'
  257. Xto ensure that at least one line is always applicable.
  258. XCross-posted articles are treated as if they were independently posted
  259. Xto each group.
  260. X.PP
  261. XThe
  262. X.B \-a
  263. Xoption specifies a default archiving directory;
  264. Xif no default is given, it is illegal for the control file to contain
  265. Xany `@' archive-directory fields.
  266. X.PP
  267. X.I Expire
  268. Xcreates subdirectories under an archiving directory automatically,
  269. Xbut will not create the archiving directory itself.
  270. XArchiving directories must be given as full pathnames.
  271. X.PP
  272. XThe
  273. X.B \-p
  274. Xoption causes an `index' line to be printed for each archived article,
  275. Xcontaining its pathname, message ID, date received, and `Subject:' line.
  276. XThe
  277. X.B \-o
  278. Xoption tells
  279. X.I expire
  280. Xto use the obsolete 4-field history-file format used by early variants
  281. Xof C news.
  282. X.PP
  283. X\fIExpire\fR and its auxiliaries recognize the standard
  284. Xenvironment variables \fB$\&NEWSARTS\fR,
  285. X\fB$\&NEWSCTL\fR, \fB$\&NEWSBIN\fR, and \fB$NEWSUMASK\fR
  286. Xwhich indicate, respectively, non-default locations
  287. Xfor news articles, news control files, and news programs,
  288. Xand a non-default \fIumask\fR (see \fIumask\fR(2)) for file creation
  289. X(the default \fIumask\fR is 002).
  290. X.SH FILES
  291. X.ta 4c
  292. X.nf
  293. X\fIlibrary\fR/history    history file
  294. X\fIlibrary\fR/history.pag    \fIdbm\fR database for history file
  295. X\fIlibrary\fR/history.dir    \fIdbm\fR database for history file
  296. X.SH SEE ALSO
  297. Xinews(1)
  298. X.SH HISTORY
  299. XWritten at U of Toronto by Henry Spencer, with contributions by Geoff Collyer.
  300. X.SH BUGS
  301. XArchiving is always done by copying, never by linking.
  302. XThis has the side effect that cross-posted articles are archived as
  303. Xseveral independent copies.
  304. X.PP
  305. XThe
  306. X.B \-p
  307. Xsubject-finder botches continued `Subject:' lines, although
  308. Xthese are rare.
  309. END_OF_FILE
  310. if test 3912 -ne `wc -c <'expire/expire.1'`; then
  311.     echo shar: \"'expire/expire.1'\" unpacked with wrong size!
  312. fi
  313. # end of 'expire/expire.1'
  314. fi
  315. if test -f 'expire/ns.p' -a "${1}" != "-c" ; then 
  316.   echo shar: Will not clobber existing file \"'expire/ns.p'\"
  317. else
  318. echo shar: Extracting \"'expire/ns.p'\" \(3614 characters\)
  319. sed "s/^X//" >'expire/ns.p' <<'END_OF_FILE'
  320. Xmkdir ns ns/foo ns/bar ns/bletch
  321. Xmkdir ns/foo/one ns/foo/two ns/foo/three
  322. Xmkdir ns/bar/one ns/bar/two ns/bar/five
  323. Xmkdir ns/bletch/one ns/bletch/four ns/bletch/six
  324. X
  325. X# The "should-expire" headers are for checking afterward.
  326. X
  327. X# In foo/one, run through the simple cases of dates before and after
  328. X# expiry dates.  Also where the Subject: line is in the article.
  329. Xoldfile 11 ns/foo/one/95 <<!
  330. XMessage-ID: <aya.foo/one/95>
  331. XShould-expire: yes
  332. XSubject: foo one/95
  333. X
  334. Xbody
  335. X!
  336. Xoldfile 10 ns/foo/one/96 <<!
  337. XMessage-ID: <bn.foo/one/96>
  338. XShould-expire: no
  339. XSubject: foo one/96
  340. X
  341. Xbody
  342. X!
  343. Xoldfile 11 ns/foo/one/97 <<!
  344. XMessage-ID: <cya.foo/one/97>
  345. XShould-expire: yes
  346. XSubject: foo one/97
  347. XExpires: `olddate 1`
  348. X
  349. Xbody
  350. X!
  351. Xoldfile 10 ns/foo/one/98 <<!
  352. XSubject: foo one/98
  353. XMessage-ID: <dn.foo/one/98>
  354. XShould-expire: no
  355. XExpires: `olddate -1`
  356. X
  357. Xbody
  358. X!
  359. Xoldfile 11 ns/foo/one/99 <<!
  360. XMessage-ID: <en.foo/one/99>
  361. XShould-expire: no
  362. XExpires: `olddate -1`
  363. XSubject: foo one/99
  364. XMumble: frotz
  365. X
  366. Xbody
  367. X!
  368. Xoldfile 10 ns/foo/one/100 <<!
  369. XSubject: foo one/100
  370. XMessage-ID: <fya.foo/one/100>
  371. XShould-expire: yes
  372. XExpires: `olddate 1`
  373. X
  374. Xbody
  375. X!
  376. X
  377. X# bar/one just has a simple pair
  378. Xoldfile 11 ns/bar/one/99 <<!
  379. XMessage-ID: <gya.bar/one/99>
  380. XShould-expire: yes
  381. XSubject: bar one/99
  382. X
  383. Xbody
  384. X!
  385. Xoldfile 10 ns/bar/one/100 <<!
  386. XMessage-ID: <hn.bar/one/100>
  387. XShould-expire: no
  388. XSubject: bar one/100
  389. X
  390. Xbody
  391. X!
  392. X
  393. X# bletch/one just has a simple pair
  394. Xoldfile 11 ns/bletch/one/99 <<!
  395. XMessage-ID: <iya.bletch/one/99>
  396. XShould-expire: yes
  397. XSubject: bletch one/99
  398. X
  399. Xbody
  400. X!
  401. Xoldfile 10 ns/bletch/one/100 <<!
  402. XMessage-ID: <jn.bletch/one/100>
  403. XShould-expire: no
  404. XSubject: bletch one/100
  405. X
  406. Xbody
  407. X!
  408. X
  409. X# foo.two has a simple pair again
  410. Xoldfile 14 ns/foo/two/99 <<!
  411. XMessage-ID: <kn.foo/two/99>
  412. XShould-expire: no
  413. XSubject: foo two/99
  414. X
  415. Xbody
  416. X!
  417. Xoldfile 16 ns/foo/two/100 <<!
  418. XMessage-ID: <lym.foo/two/100>
  419. XShould-expire: yes
  420. XSubject: foo two/100
  421. X
  422. Xbody
  423. X!
  424. X
  425. X# bar.two, another simple pair
  426. Xoldfile 14 ns/bar/two/99 <<!
  427. XMessage-ID: <mn.bar/two/99>
  428. XShould-expire: no
  429. XSubject: bar two/99
  430. X
  431. Xbody
  432. X!
  433. Xoldfile 16 ns/bar/two/100 <<!
  434. XMessage-ID: <nym.bar/two/100>
  435. XShould-expire: yes
  436. XSubject: bar two/100
  437. X
  438. Xbody
  439. X!
  440. X
  441. X# foo.three adds a purge date
  442. Xoldfile 4 ns/foo/three/98 <<!
  443. XMessage-ID: <on.foo/three/98>
  444. XShould-expire: no
  445. XSubject: foo three/98
  446. X
  447. Xbody
  448. X!
  449. Xoldfile 6 ns/foo/three/99 <<!
  450. XMessage-ID: <pyu.foo/three/99>
  451. XShould-expire: yes
  452. XSubject: foo three/99
  453. X
  454. Xbody
  455. X!
  456. Xoldfile 16 ns/foo/three/100 <<!
  457. XMessage-ID: <qyu.foo/three/100>
  458. XShould-expire: yes
  459. XExpires: `olddate -1`
  460. XSubject: foo three/100
  461. X
  462. Xbody
  463. X!
  464. X
  465. X# bletch.four has both a retain date and a purge date
  466. Xoldfile 9 ns/bletch/four/97 <<!
  467. XMessage-ID: <rn.bletch/four/97>
  468. XShould-expire: no
  469. XSubject: bletch four/97
  470. X
  471. Xbody
  472. X!
  473. Xoldfile 11 ns/bletch/four/98 <<!
  474. XMessage-ID: <sym.bletch/four/98>
  475. XShould-expire: yes
  476. XSubject: bletch four/98
  477. X
  478. Xbody
  479. X!
  480. Xoldfile 3 ns/bletch/four/99 <<!
  481. XMessage-ID: <tn.bletch/four/99>
  482. XShould-expire: no
  483. XExpires: `olddate 1`
  484. XSubject: bletch four/99
  485. X
  486. Xbody
  487. X!
  488. Xoldfile 25 ns/bletch/four/100 <<!
  489. XMessage-ID: <uym.bletch/four/100>
  490. XShould-expire: yes
  491. XExpires: `olddate -1`
  492. XSubject: bletch four/100
  493. X
  494. Xbody
  495. X!
  496. X
  497. X# bar.five gets the catchall at the end and is another simple pair.
  498. Xoldfile 31 ns/bar/five/99 <<!
  499. XMessage-ID: <vy-.bar/five/99>
  500. XShould-expire: yes
  501. XSubject: bar five/99
  502. X
  503. Xbody
  504. X!
  505. Xoldfile 29 ns/bar/five/100 <<!
  506. XMessage-ID: <wn.bar/five/100>
  507. XShould-expire: no
  508. XSubject: bar five/100
  509. X
  510. Xbody
  511. X!
  512. X
  513. X# bletch.six is not in the active file, but is otherwise orthodox
  514. Xoldfile 31 ns/bletch/six/99 <<!
  515. XMessage-ID: <xy-.bletch/six/99>
  516. XShould-expire: yes
  517. XSubject: bletch six/99
  518. X
  519. Xbody
  520. X!
  521. Xoldfile 29 ns/bletch/six/100 <<!
  522. XMessage-ID: <yn.bletch/six/100>
  523. XShould-expire: no
  524. XSubject: bletch six/100
  525. X
  526. Xbody
  527. X!
  528. END_OF_FILE
  529. if test 3614 -ne `wc -c <'expire/ns.p'`; then
  530.     echo shar: \"'expire/ns.p'\" unpacked with wrong size!
  531. fi
  532. # end of 'expire/ns.p'
  533. fi
  534. if test -f 'expire/xargs.c' -a "${1}" != "-c" ; then 
  535.   echo shar: Will not clobber existing file \"'expire/xargs.c'\"
  536. else
  537. echo shar: Extracting \"'expire/xargs.c'\" \(3713 characters\)
  538. sed "s/^X//" >'expire/xargs.c' <<'END_OF_FILE'
  539. X/*
  540. X * xargs - gather up filenames from input and run command on them
  541. X */
  542. X
  543. X#include <stdio.h>
  544. X#include <sys/param.h>
  545. X
  546. X#define    STREQ(a, b)    (strcmp((a), (b)) == 0)
  547. X
  548. X#ifndef lint
  549. Xstatic char Sccsid[] = "@(#)xargs.c    1.2 of 6 May 86";
  550. X#endif
  551. X
  552. Xchar argchars[NCARGS];        /* Characters of arguments. */
  553. Xchar *argfree = argchars;    /* First free char in argchars. */
  554. Xchar *argbase = argchars;    /* First char after constant args. */
  555. X
  556. Xchar *argptrs[NCARGS/sizeof(char *)];    /* Pointers to arguments. */
  557. Xint nargs = 0;            /* Number of entries in argptrs. */
  558. Xint base = 0;            /* Number of constant entries. */
  559. X
  560. Xint size = 0;            /* Size of total argument bundle so far. */
  561. Xint basesize = 0;        /* Size of constant args. */
  562. X#ifndef XARGMAX
  563. X#define    XARGMAX    (NCARGS - 50)    /* 50 is misc. overhead plus safety margin. */
  564. X#endif
  565. X
  566. X#ifndef OKSTAT
  567. X#define    OKSTAT    1        /* Highest exit status considered normal. */
  568. X#endif
  569. X
  570. Xextern char **environ;
  571. X
  572. Xchar *progname;
  573. Xextern char *mkprogname();
  574. X
  575. X/*
  576. X * main - parse arguments, handle options, main control
  577. X */
  578. Xmain(argc, argv)
  579. Xint argc;
  580. Xchar *argv[];
  581. X{
  582. X    int c;
  583. X    int errflg = 0;
  584. X    char *cmd;
  585. X    register char **envp;
  586. X    char buf[BUFSIZ];
  587. X    register int len;
  588. X    int maxstat = 0;
  589. X    int thisstat;
  590. X    extern int optind;
  591. X    extern char *optarg;
  592. X
  593. X    progname = mkprogname(argv[0]);
  594. X
  595. X    while ((c = getopt(argc, argv, "")) != EOF)
  596. X        switch (c) {
  597. X        case '?':
  598. X        default:
  599. X            errflg++;
  600. X            break;
  601. X        }
  602. X    if (errflg || optind == argc) {
  603. X        fprintf(stderr, "Usage: %s command [arg] ...\n", progname);
  604. X        exit(2);
  605. X    }
  606. X
  607. X    /* Plug in the constant arguments. */
  608. X    cmd = argv[optind];
  609. X    for (; optind < argc; optind++) {
  610. X        argptrs[nargs++] = argv[optind];
  611. X        size += strlen(argv[optind]) + 1 + sizeof(char *);
  612. X    }
  613. X
  614. X    /* Add in the size of the environment. */
  615. X    for (envp = environ; *envp != NULL; envp++)
  616. X        size += strlen(*envp) + 1 + sizeof(char *);
  617. X
  618. X    /* Establish base. */
  619. X    argbase = argfree;
  620. X    base = nargs;
  621. X    basesize = size;
  622. X    if (basesize >= XARGMAX) {
  623. X        fprintf(stderr, "%s: command too big\n", progname);
  624. X        exit(2);
  625. X    }
  626. X
  627. X    /* And do it. */
  628. X    while (fgets(buf, (int)sizeof(buf), stdin) != NULL) {
  629. X        len = strlen(buf);
  630. X        if (buf[len-1] == '\n')
  631. X            buf[len-1] = '\0';
  632. X        if (basesize + len + 1 + sizeof(char *) >= XARGMAX) {
  633. X            fprintf(stderr, "%s: filename too long: ", progname);
  634. X            fputs(buf, stdout);
  635. X            putchar('\n');
  636. X        } else {
  637. X            if (size + len + 1 + sizeof(char *) >= XARGMAX) {
  638. X                argptrs[nargs++] = NULL;
  639. X                thisstat = runone(cmd, argptrs);
  640. X                if (thisstat > maxstat)
  641. X                    maxstat = thisstat;
  642. X                argfree = argbase;
  643. X                nargs = base;
  644. X                size = basesize;
  645. X            }
  646. X            (void) strcpy(argfree, buf);
  647. X            argptrs[nargs++] = argfree;
  648. X            argfree += len + 1;
  649. X            size += len + 1 + sizeof(char *);
  650. X        }
  651. X    }
  652. X    if (nargs > base) {    /* If there are any loose ends... */
  653. X        argptrs[nargs++] = NULL;
  654. X        thisstat = runone(cmd, argptrs);
  655. X        if (thisstat > maxstat)
  656. X            maxstat = thisstat;
  657. X    }
  658. X
  659. X    exit(maxstat);
  660. X}
  661. X
  662. X/*
  663. X * runone - run the command
  664. X */
  665. Xint                /* status of command */
  666. Xrunone(cmd, ptrs)
  667. Xchar *cmd;
  668. Xchar **ptrs;
  669. X{
  670. X    register int pid;
  671. X    int status;
  672. X    int stexit, stcause;
  673. X    register int wpid;
  674. X
  675. X#ifdef DEBUG
  676. X    fprintf(stderr, "run %s ... %s %s ...\n", cmd, ptrs[0], ptrs[1]);
  677. X#endif
  678. X    while ((pid = fork()) < 0)
  679. X        sleep(10);
  680. X    if (pid == 0) {        /* Daughter. */
  681. X        close(0);
  682. X        if (open("/dev/null", 0) != 0) {
  683. X            fprintf(stderr, "%s: can't open /dev/null\n", progname);
  684. X            exit(2);
  685. X        }
  686. X        execvp(cmd, ptrs);
  687. X        fprintf(stderr, "%s: can't find `%s'\n", progname, cmd);
  688. X        exit(2);
  689. X    } else {        /* Parent. */
  690. X        do {
  691. X            wpid = wait(&status);
  692. X        } while (wpid >= 0 && wpid != pid);
  693. X        stexit = (status>>8)&0377;
  694. X        stcause = status&0377;
  695. X        if (stcause != 0 || stexit > OKSTAT) {
  696. X            fprintf(stderr, "%s: `%s' failed\n", progname, cmd);
  697. X            exit(2);
  698. X        }
  699. X        return(stexit);
  700. X    }
  701. X    /* NOTREACHED */
  702. X}
  703. END_OF_FILE
  704. if test 3713 -ne `wc -c <'expire/xargs.c'`; then
  705.     echo shar: \"'expire/xargs.c'\" unpacked with wrong size!
  706. fi
  707. # end of 'expire/xargs.c'
  708. fi
  709. if test -f 'libcnews/path.c' -a "${1}" != "-c" ; then 
  710.   echo shar: Will not clobber existing file \"'libcnews/path.c'\"
  711. else
  712. echo shar: Extracting \"'libcnews/path.c'\" \(3615 characters\)
  713. sed "s/^X//" >'libcnews/path.c' <<'END_OF_FILE'
  714. X/*
  715. X * news path names (and umask)
  716. X */
  717. X
  718. X#include <stdio.h>
  719. X#include <sys/types.h>
  720. X#include "news.h"
  721. X#include "newspaths.h"
  722. X
  723. X#ifndef NULL
  724. X#define    NULL    0
  725. X#endif
  726. X
  727. X#ifndef NEWSCTL
  728. X#define NEWSCTL "/usr/lib/news"
  729. X#endif
  730. X#ifndef NEWSARTS
  731. X#define NEWSARTS "/usr/spool/news"
  732. X#endif
  733. X#ifndef NEWSBIN
  734. X#define    NEWSBIN    "/usr/lib/newsbin"
  735. X#endif
  736. X#ifndef NEWSUMASK
  737. X#define    NEWSUMASK    002
  738. X#endif
  739. X
  740. Xstatic char *pwd = NULL;    /* Current directory, NULL means unknown. */
  741. Xstatic int dirsset = NO;    /* Have the following been set? */
  742. Xstatic char *arts;
  743. Xstatic char *bin;
  744. Xstatic char *ctl;
  745. X#define    DIRS()    if (!dirsset) setdirs()
  746. Xvoid setdirs();
  747. X
  748. Xextern char *strcpy();
  749. Xextern char *strcat();
  750. Xextern char *getenv();
  751. X
  752. Xextern void unprivileged();    /* user-supplied privilege dropper */
  753. X
  754. X/*
  755. X - spoolfile - historical synonym for artfile
  756. X */
  757. Xchar *
  758. Xspoolfile(base)
  759. Xchar *base;
  760. X{
  761. X    static char wholefile[MAXFILE];
  762. X
  763. X    DIRS();
  764. X
  765. X    if (base == NULL) {    /* he just wants the directory */
  766. X        (void) strcpy(wholefile, arts);
  767. X        return wholefile;
  768. X    }
  769. X
  770. X    if (pwd != NULL && STREQ(pwd, arts))
  771. X        (void) strcpy(wholefile, "");
  772. X    else {
  773. X        (void) strcpy(wholefile, arts);
  774. X        (void) strcat(wholefile, SFNDELIM);
  775. X    }
  776. X    (void) strcat(wholefile, base);
  777. X
  778. X    return wholefile;
  779. X}
  780. X
  781. X/*
  782. X - artfile - best pathname for a file in NEWSARTS
  783. X */
  784. Xchar *
  785. Xartfile(base)
  786. Xchar *base;
  787. X{
  788. X    return spoolfile(base);
  789. X}
  790. X
  791. X/*
  792. X - fullartfile - full pathname for a file in NEWSARTS
  793. X */
  794. Xchar *
  795. Xfullartfile(base)
  796. Xchar *base;
  797. X{
  798. X    register char *p;
  799. X    register char *pwdsave;
  800. X
  801. X    pwdsave = pwd;
  802. X    pwd = NULL;        /* fool spoolfile() into giving full path */
  803. X    p = spoolfile(base);
  804. X    pwd = pwdsave;
  805. X    return p;
  806. X}
  807. X
  808. X/*
  809. X - fullspoolfile - historical synonym for fullartfile
  810. X */
  811. Xchar *
  812. Xfullspoolfile(base)
  813. Xchar *base;
  814. X{
  815. X    return fullartfile(base);
  816. X}
  817. X
  818. X/*
  819. X - libfile - historical synonym for ctlfile
  820. X */
  821. Xchar *
  822. Xlibfile(base)
  823. Xchar *base;
  824. X{
  825. X    static char wholefile[MAXFILE];
  826. X
  827. X    DIRS();
  828. X
  829. X    (void) strcpy(wholefile, ctl);
  830. X    if (base != NULL) {
  831. X        (void) strcat(wholefile, SFNDELIM);
  832. X        (void) strcat(wholefile, base);
  833. X    }
  834. X    return wholefile;
  835. X}
  836. X
  837. X/*
  838. X - ctlfile - full pathname for a file in NEWSCTL
  839. X */
  840. Xchar *
  841. Xctlfile(base)
  842. Xchar *base;
  843. X{
  844. X    return libfile(base);
  845. X}
  846. X
  847. X/*
  848. X - binfile - full pathname for a file in NEWSBIN
  849. X */
  850. Xchar *
  851. Xbinfile(base)
  852. Xchar *base;
  853. X{
  854. X    static char wholefile[MAXFILE];
  855. X
  856. X    DIRS();
  857. X
  858. X    (void) strcpy(wholefile, bin);
  859. X    if (base != NULL) {
  860. X        (void) strcat(wholefile, SFNDELIM);
  861. X        (void) strcat(wholefile, base);
  862. X    }
  863. X    return wholefile;
  864. X}
  865. X
  866. X/*
  867. X - cd - change to a directory, with checking
  868. X */
  869. Xvoid
  870. Xcd(dir)
  871. Xchar *dir;
  872. X{
  873. X    if (chdir(dir) < 0)
  874. X        errunlock("cannot chdir(%s)", dir);
  875. X    pwd = dir;
  876. X}
  877. X
  878. X/*
  879. X - setdirs - set up directories from environment, for use by other functions
  880. X *
  881. X * Invokes user-supplied function unprivileged() if non-standard values used.
  882. X */
  883. Xstatic void
  884. Xsetdirs()
  885. X{
  886. X    register char *p;
  887. X    register int nonstd = NO;
  888. X
  889. X    if (dirsset)
  890. X        return;
  891. X
  892. X    p = getenv("NEWSARTS");
  893. X    if (p == NULL)
  894. X        arts = NEWSARTS;
  895. X    else {
  896. X        arts = p;
  897. X        nonstd = YES;
  898. X    }
  899. X
  900. X    p = getenv("NEWSCTL");
  901. X    if (p == NULL)
  902. X        ctl = NEWSCTL;
  903. X    else {
  904. X        ctl = p;
  905. X        nonstd = YES;
  906. X    }
  907. X
  908. X    p = getenv("NEWSBIN");
  909. X    if (p == NULL)
  910. X        bin = NEWSBIN;
  911. X    else {
  912. X        bin = p;
  913. X        nonstd = YES;
  914. X    }
  915. X
  916. X    dirsset = YES;
  917. X    if (nonstd)
  918. X        unprivileged();
  919. X}
  920. X
  921. X/*
  922. X - newsumask - return suitable value of umask for news stuff
  923. X */
  924. Xint
  925. Xnewsumask()
  926. X{
  927. X    register char *p;
  928. X    register char *scan;
  929. X    register int mask;
  930. X
  931. X    p = getenv("NEWSUMASK");
  932. X    if (p == NULL)
  933. X        return(NEWSUMASK);
  934. X    else {
  935. X        mask = 0;
  936. X        for (scan = p; *scan != '\0'; scan++)
  937. X            if ('0' <= *scan && *scan <= '7' && mask <= 077)
  938. X                mask = (mask << 3) | (*scan - '0');
  939. X            else    /* Garbage, ignore it. */
  940. X                return(NEWSUMASK);
  941. X        return(mask);
  942. X    }
  943. X}
  944. END_OF_FILE
  945. if test 3615 -ne `wc -c <'libcnews/path.c'`; then
  946.     echo shar: \"'libcnews/path.c'\" unpacked with wrong size!
  947. fi
  948. # end of 'libcnews/path.c'
  949. fi
  950. if test -f 'mail/coder/uudecode.c' -a "${1}" != "-c" ; then 
  951.   echo shar: Will not clobber existing file \"'mail/coder/uudecode.c'\"
  952. else
  953. echo shar: Extracting \"'mail/coder/uudecode.c'\" \(3280 characters\)
  954. sed "s/^X//" >'mail/coder/uudecode.c' <<'END_OF_FILE'
  955. X
  956. X/* based on 5.1 (Berkeley) 7/2/83 */
  957. X
  958. X/*
  959. X * uudecode [input]
  960. X *
  961. X * create the specified file, decoding as you go.
  962. X * used with uuencode.
  963. X */
  964. X#include <stdio.h>
  965. X#include <pwd.h>
  966. X#include <sys/types.h>
  967. X#include <sys/stat.h>
  968. X
  969. Xmain(argc, argv)
  970. Xchar **argv;
  971. X{
  972. X    FILE *in, *out;
  973. X    int mode = 0777;
  974. X    char dest[128];
  975. X    char buf[80];
  976. X    char *strcpy(), *strcat();
  977. X
  978. X    /* optional input arg */
  979. X    if (argc > 1) {
  980. X        if ((in = fopen(argv[1], "r")) == NULL) {
  981. X            perror(argv[1]);
  982. X            exit(1);
  983. X        }
  984. X        argv++; argc--;
  985. X    } else
  986. X        in = stdin;
  987. X
  988. X    if (argc != 1) {
  989. X        (void) fprintf(stderr, "Usage: uudecode [infile]\n");
  990. X        exit(2);
  991. X    }
  992. X
  993. X    /* search for header line */
  994. X    for (;;) {
  995. X        if (fgets(buf, sizeof buf, in) == NULL) {
  996. X            (void) fprintf(stderr, "No begin line\n");
  997. X            exit(3);
  998. X        }
  999. X        if (strncmp(buf, "begin ", 6) == 0)
  1000. X            break;
  1001. X    }
  1002. X    dest[0] = '\0';
  1003. X    (void) sscanf(buf, "begin %o %s", &mode, dest);
  1004. X
  1005. X    /* handle ~user/file format */
  1006. X    if (dest[0] == '~') {
  1007. X        char *sl;
  1008. X        struct passwd *getpwnam();
  1009. X        char *index();
  1010. X        struct passwd *user;
  1011. X        char dnbuf[100];
  1012. X
  1013. X        sl = index(dest, '/');
  1014. X        if (sl == NULL) {
  1015. X            (void) fprintf(stderr, "Illegal ~user\n");
  1016. X            exit(3);
  1017. X        }
  1018. X        *sl++ = 0;
  1019. X        user = getpwnam(dest+1);
  1020. X        if (user == NULL) {
  1021. X            (void) fprintf(stderr, "No such user as %s\n", dest);
  1022. X            exit(4);
  1023. X        }
  1024. X        (void) strcpy(dnbuf, user->pw_dir);
  1025. X        (void) strcat(dnbuf, "/");
  1026. X        (void) strcat(dnbuf, sl);
  1027. X        (void) strcpy(dest, dnbuf);
  1028. X    }
  1029. X
  1030. X    /* create output file */
  1031. X    out = fopen(dest, "w");
  1032. X    if (out == NULL) {
  1033. X        perror(dest);
  1034. X        exit(4);
  1035. X    }
  1036. X    (void) chmod(dest, mode);
  1037. X
  1038. X    decode(in, out);
  1039. X
  1040. X    if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) {
  1041. X        (void) fprintf(stderr, "No end line\n");
  1042. X        exit(5);
  1043. X    }
  1044. X    exit(0);
  1045. X}
  1046. X
  1047. X/*
  1048. X * copy from in to out, decoding as you go along.
  1049. X */
  1050. Xdecode(in, out)
  1051. XFILE *in;
  1052. XFILE *out;
  1053. X{
  1054. X    register char *ibp, *obp;
  1055. X    register int inbyte, outbyte;
  1056. X    register int loops, incount;
  1057. X    char inbuf[120];        /* allow for uuencode to grow lines */
  1058. X    char outbuf[120];
  1059. X
  1060. X/* single character decode */
  1061. X#define DEC(c)    (((c) - ' ') & 077)    /* N.B.: c is evaluated exactly once */
  1062. X
  1063. X    for (; ; ) {
  1064. X        if (fgets(inbuf, sizeof inbuf, in) == NULL) {
  1065. X            (void) printf("Short file\n");
  1066. X            exit(10);        /* premature EOF */
  1067. X        }
  1068. X        incount = DEC(inbuf[0]);
  1069. X        if (incount <= 0)
  1070. X            break;            /* EOF */
  1071. X
  1072. X        ibp = &inbuf[1];        /* skip line length */
  1073. X        obp = outbuf;
  1074. X        for (loops = incount / 3; --loops >= 0; ) {    /* inner loop */
  1075. X            /*
  1076. X             * output a group of 3 bytes (4 input characters).
  1077. X             * the input chars are pointed to by ibp, they are to
  1078. X             * be output via obp.  incount is used to tell us
  1079. X             * not to output all of them at the end of the line.
  1080. X             */
  1081. X            outbyte = DEC(*ibp++) << 2;
  1082. X            *obp++ = outbyte | ((inbyte = DEC(*ibp++)) >> 4);
  1083. X            outbyte = inbyte << 4;
  1084. X            *obp++ = outbyte | ((inbyte = DEC(*ibp++)) >> 2);
  1085. X            *obp++ = (inbyte << 6) | DEC(*ibp++);
  1086. X        }
  1087. X        loops = incount % 3;
  1088. X        if (loops > 0) {
  1089. X            /*
  1090. X             * finish off the remaining bytes (loops < 3).
  1091. X             */
  1092. X            if (--loops >= 0) {
  1093. X                outbyte = DEC(*ibp++) << 2;
  1094. X                *obp++ = outbyte | ((inbyte = DEC(*ibp++)) >> 4);
  1095. X            }
  1096. X            if (--loops >= 0) {
  1097. X                outbyte = inbyte << 4;
  1098. X                *obp++ = outbyte | ((inbyte = DEC(*ibp++)) >> 2);
  1099. X            }
  1100. X            if (--loops >= 0)
  1101. X                *obp++ = (inbyte << 6) | DEC(*ibp++);
  1102. X        }
  1103. X        *obp = '\0';
  1104. X        (void) fwrite(outbuf, 1, obp - outbuf, out);
  1105. X    }
  1106. X}
  1107. END_OF_FILE
  1108. if test 3280 -ne `wc -c <'mail/coder/uudecode.c'`; then
  1109.     echo shar: \"'mail/coder/uudecode.c'\" unpacked with wrong size!
  1110. fi
  1111. # end of 'mail/coder/uudecode.c'
  1112. fi
  1113. if test -f 'rna/active.c' -a "${1}" != "-c" ; then 
  1114.   echo shar: Will not clobber existing file \"'rna/active.c'\"
  1115. else
  1116. echo shar: Extracting \"'rna/active.c'\" \(3032 characters\)
  1117. sed "s/^X//" >'rna/active.c' <<'END_OF_FILE'
  1118. X/*
  1119. X * active file handling routines
  1120. X *
  1121. X * format of file:
  1122. X *    <groupname> ' ' <5 digit #> ' ' <5 digit #> ' ' flag '\n'
  1123. X *              (seq)          (low)
  1124. X */
  1125. X
  1126. X#include "defs.h"
  1127. X
  1128. Xstatic char actname[]     = ACTIVE;
  1129. Xstatic int lineno;
  1130. Xstatic active    *alist;
  1131. X
  1132. X/*
  1133. X * getseq - Get next sequence number for this group
  1134. X *        and update active file.
  1135. X *        If group missing append to file.
  1136. X */
  1137. Xchar *
  1138. Xgetseq(group)
  1139. Xchar *group;
  1140. X{
  1141. X    register FILE    *f;
  1142. X    register int i;
  1143. X    char gbuf[BUFSIZ / 2], dbuf[BUFSIZ / 4], dbuf2[BUFSIZ / 4];
  1144. X    extern char *itoa();
  1145. X
  1146. X    f = fopenl(actname);
  1147. X    lineno = 0;
  1148. X    while (getline(f, gbuf, dbuf, dbuf2))
  1149. X        if (CMP(gbuf, group) == 0) {
  1150. X            i = atoi(dbuf);
  1151. X            i++;
  1152. X            fseek(f, -12L, 1);
  1153. X            (void) fprintf(f, "%05d", i);
  1154. X            fclose(f);
  1155. X#if !AUSAM
  1156. X            unlock(actname);
  1157. X#endif
  1158. X            return itoa(i);
  1159. X        }
  1160. X    (void) fprintf(f, "%s 00001 00001 y\n", group);
  1161. X    fclose(f);
  1162. X#if !AUSAM
  1163. X    unlock(actname);
  1164. X#endif
  1165. X    return itoa(1);
  1166. X}
  1167. X
  1168. X
  1169. Xstatic
  1170. Xgetline(f, g, d, d2)
  1171. Xregister FILE *f;
  1172. Xchar *g, *d, *d2;
  1173. X{
  1174. X    register int c;
  1175. X    register char *s;
  1176. X
  1177. X    lineno++;
  1178. X    s = g;
  1179. X    while ((c = getc(f)) != ' ' && c != EOF)
  1180. X        *s++ = c;
  1181. X    *s = '\0';
  1182. X
  1183. X    if (c != EOF) {
  1184. X        s = d;
  1185. X        while ((c = getc(f)) != EOF && isdigit(c))
  1186. X            *s++ = c;
  1187. X        *s = '\0';
  1188. X
  1189. X        s = d2;
  1190. X        if (c == ' ')
  1191. X            while ((c = getc(f)) != EOF && isdigit(c))
  1192. X                *s++ = c;
  1193. X        *s = '\0';
  1194. X
  1195. X        if (c == ' ')
  1196. X            while ((c = getc(f)) != EOF && c != '\n')
  1197. X                ;        /* eat flag */
  1198. X    }
  1199. X
  1200. X    if (c != EOF && (c != '\n' || !*d || !*d2))
  1201. X        error("%s: bad format: line %d", actname, lineno);
  1202. X    return c != EOF;
  1203. X}
  1204. X
  1205. X
  1206. X/*
  1207. X * build internal active file structure
  1208. X */
  1209. Xactive *
  1210. Xreadactive()
  1211. X{
  1212. X    register FILE    *f;
  1213. X    register active    *ap, *last;
  1214. X    char gbuf[BUFSIZ / 2], dbuf[BUFSIZ / 4], dbuf2[BUFSIZ / 4];
  1215. X
  1216. X    alist = last = NIL(active);
  1217. X    f = fopenf(actname, "r");
  1218. X    lineno = 0;
  1219. X    while (getline(f, gbuf, dbuf, dbuf2)) {
  1220. X        ap = NEW(active);
  1221. X        ap->a_name = newstr(gbuf);
  1222. X        ap->a_seq = atoi(dbuf);
  1223. X        ap->a_low = atoi(dbuf2);
  1224. X        ap->a_next = NIL(active);
  1225. X        if (!alist)
  1226. X            alist = ap;
  1227. X        else
  1228. X            last->a_next = ap;
  1229. X        last = ap;
  1230. X    }
  1231. X    fclose(f);
  1232. X    return alist;
  1233. X}
  1234. X
  1235. X
  1236. X/*
  1237. X * return pointer to named group
  1238. X */
  1239. Xactive *
  1240. Xactivep(grp)
  1241. Xregister char *grp;
  1242. X{
  1243. X    register active    *ap;
  1244. X
  1245. X    for (ap = alist; ap; ap = ap->a_next)
  1246. X        if (CMP(grp, ap->a_name) == 0)
  1247. X            break;
  1248. X    return ap;
  1249. X}
  1250. X
  1251. X
  1252. X/*
  1253. X * setlow - set the low number for this group
  1254. X */
  1255. Xsetlow(group, low)
  1256. Xchar *group;
  1257. Xint low;
  1258. X{
  1259. X    register FILE    *f;
  1260. X    char gbuf[BUFSIZ / 2], dbuf[BUFSIZ / 4], dbuf2[BUFSIZ / 4];
  1261. X    extern char *itoa();
  1262. X
  1263. X    f = fopenl(actname);
  1264. X    lineno = 0;
  1265. X    while (getline(f, gbuf, dbuf, dbuf2))
  1266. X        if (CMP(gbuf, group) == 0) {
  1267. X            fseek(f, -6L, 1);
  1268. X            (void) fprintf(f, "%05d", low);
  1269. X            break;
  1270. X        }
  1271. X    fclose(f);
  1272. X#if !AUSAM
  1273. X    unlock(actname);
  1274. X#endif
  1275. X}
  1276. X
  1277. X
  1278. X
  1279. X/*
  1280. X * initgrp - initialise an entry for this group
  1281. X */
  1282. Xinitgrp(group)
  1283. Xchar *group;
  1284. X{
  1285. X    register FILE    *f;
  1286. X    char gbuf[BUFSIZ / 2], dbuf[BUFSIZ / 4], dbuf2[BUFSIZ / 4];
  1287. X
  1288. X    f = fopenl(actname);
  1289. X    lineno = 0;
  1290. X    while (getline(f, gbuf, dbuf, dbuf2))
  1291. X        if (CMP(gbuf, group) == 0) {
  1292. X#if !AUSAM
  1293. X            unlock(actname);
  1294. X#endif
  1295. X            return;
  1296. X        }
  1297. X    (void) fprintf(f, "%s 00000 00001\n", group);
  1298. X
  1299. X}
  1300. END_OF_FILE
  1301. if test 3032 -ne `wc -c <'rna/active.c'`; then
  1302.     echo shar: \"'rna/active.c'\" unpacked with wrong size!
  1303. fi
  1304. # end of 'rna/active.c'
  1305. fi
  1306. if test -f 'rna/history.c' -a "${1}" != "-c" ; then 
  1307.   echo shar: Will not clobber existing file \"'rna/history.c'\"
  1308. else
  1309. echo shar: Extracting \"'rna/history.c'\" \(3647 characters\)
  1310. sed "s/^X//" >'rna/history.c' <<'END_OF_FILE'
  1311. X/*
  1312. X * History file
  1313. X * each line contains a message-id, install or expire time
  1314. X * names of linked files
  1315. X */
  1316. X
  1317. X#include "defs.h"
  1318. X
  1319. Xstatic char histname[]     = HISTORY;
  1320. Xstatic char *histid;            /* messageid to save */
  1321. Xstatic char *histline;            /* list of linked files */
  1322. Xstatic long etime;            /* expire time */
  1323. X
  1324. Xtypedef enum stypes { 
  1325. X    chk, delete } stype;
  1326. X
  1327. X/*
  1328. X * do things with history file
  1329. X * chk - see if id present
  1330. X * delete - delete article with id
  1331. X */
  1332. Xstatic bool
  1333. Xsearchhist(id, type)
  1334. Xchar *id;
  1335. Xstype type;
  1336. X{
  1337. X    register FILE    *f;
  1338. X    register char *s, *name;
  1339. X    register bool    found;
  1340. X    char buf[BUFSIZ * 2];
  1341. X
  1342. X    extern char *newsdir;
  1343. X
  1344. X    f = fopenl(histname);
  1345. X
  1346. X    found = false;
  1347. X    while (fgets(buf, sizeof(buf), f)) {
  1348. X        if (s = strchr(buf, ' '))
  1349. X            *s = '\0';
  1350. X        else
  1351. X            error("Bad format: %s", histname);
  1352. X        if (CMP(buf, id) == 0) {
  1353. X            found = true;
  1354. X            break;
  1355. X        }
  1356. X    }
  1357. X    if (found && type == delete) {
  1358. X        if ((name = strchr(s + 1, ' ')) == NIL(char))
  1359. X            error("Bad format: %s", histname);
  1360. X        name++;
  1361. X        while (name && (s = strpbrk(name, " \n"))) {
  1362. X            *s = '\0';
  1363. X            name = newstr3(newsdir, "/", name);
  1364. X            remove(name);
  1365. X            free(name);
  1366. X            name = s + 1;
  1367. X        }
  1368. X    }
  1369. X    fclose(f);
  1370. X#if !AUSAM
  1371. X    unlock(histname);
  1372. X#endif
  1373. X    return found;
  1374. X}
  1375. X
  1376. X
  1377. X/*
  1378. X * delete files given id
  1379. X */
  1380. Xbool
  1381. Xcancel(id)
  1382. Xchar *id;
  1383. X{
  1384. X    bool searchhist();
  1385. X
  1386. X    return searchhist(id, delete);
  1387. X}
  1388. X
  1389. X
  1390. X/*
  1391. X * check if article has been recieved
  1392. X */
  1393. Xbool
  1394. Xchkhist(id)
  1395. Xchar *id;
  1396. X{
  1397. X    bool searchhist();
  1398. X
  1399. X    return searchhist(id, chk);
  1400. X}
  1401. X
  1402. X
  1403. X/*
  1404. X * scan history, clearing uflag list entry if id not seen
  1405. X */
  1406. Xscanhist(ulist, usize)
  1407. Xchar **ulist;
  1408. Xint usize;
  1409. X{
  1410. X    register FILE    *f;
  1411. X    register char *s, **found;
  1412. X    register int i;
  1413. X    char *key[1];
  1414. X    char buf[BUFSIZ * 2];
  1415. X    bool         * seen;
  1416. X
  1417. X    extern char *newsdir;
  1418. X
  1419. X    seen = (bool * ) myalloc((int) sizeof(bool) * usize);
  1420. X    memset((char *)seen, 0, (int) sizeof(bool) * usize);
  1421. X
  1422. X    f = fopenf(histname, "r");
  1423. X    while (fgets(buf, sizeof(buf), f)) {
  1424. X        if (s = strchr(buf, ' '))
  1425. X            *s = '\0';
  1426. X        else
  1427. X            error("Bad format: %s", histname);
  1428. X        key[0] = buf;
  1429. X        found = (char **) bsearch((char *) key, (char *) ulist, (unsigned) usize,
  1430. X             sizeof(char *), strpcmp);
  1431. X        if (found)
  1432. X            seen[found - ulist] = true;
  1433. X    }
  1434. X    fclose(f);
  1435. X
  1436. X    for (i = 0; i < usize; i++)
  1437. X        if (!seen[i]) {
  1438. X            free(ulist[i]);
  1439. X            ulist[i] = NIL(char);
  1440. X        }
  1441. X    free((char *)seen);
  1442. X}
  1443. X
  1444. X
  1445. X/*
  1446. X * open hist file, write id and time
  1447. X */
  1448. Xopenhist(hp)
  1449. Xheader *hp;
  1450. X{
  1451. X
  1452. X    histid = newstr(hp->h_messageid);
  1453. X    if (hp->h_expires)
  1454. X        etime = atot(hp->h_expires);
  1455. X    else
  1456. X        etime = 0L;
  1457. X    histline = NIL(char);
  1458. X}
  1459. X
  1460. X
  1461. X/*
  1462. X * write name of file article resides into history file
  1463. X */
  1464. Xwritehist(fname)
  1465. Xchar *fname;
  1466. X{
  1467. X    histline = (histline ? catstr2(histline, " ", fname) : newstr(fname));
  1468. X}
  1469. X
  1470. X
  1471. X/*
  1472. X * close history file
  1473. X */
  1474. Xclosehist()
  1475. X{
  1476. X    register FILE    *f;
  1477. X    extern long now;
  1478. X
  1479. X    f = fopenl(histname);
  1480. X    fseek(f, 0L, 2);
  1481. X    (void) fprintf(f, "%s %s%ld %s\n", histid, etime ? "E" : "", etime ? etime :
  1482. X        now, histline);
  1483. X    fclose(f);
  1484. X#if !AUSAM
  1485. X    unlock(histname);
  1486. X#endif
  1487. X    free(histid); 
  1488. X    free(histline);
  1489. X}
  1490. X
  1491. X
  1492. X/*
  1493. X * remove a news item
  1494. X * check owner first
  1495. X */
  1496. Xstatic
  1497. Xremove(fname)
  1498. Xchar *fname;
  1499. X{
  1500. X    header            h;
  1501. X    FILE             * f;
  1502. X    register char *s, *mname;
  1503. X
  1504. X#if AUSAM
  1505. X    extern struct pwent pe;
  1506. X#else
  1507. X    extern struct passwd *pp;
  1508. X#endif
  1509. X    extern char systemid[];
  1510. X    extern bool        su;
  1511. X    extern bool        pflag;
  1512. X
  1513. X    if (!su && !pflag) {
  1514. X        f = fopenf(fname, "r");
  1515. X        gethead(f, &h);
  1516. X        fclose(f);
  1517. X        if (s = strchr(h.h_from, ' '))
  1518. X            *s = '\0';
  1519. X        mname = newstr5(
  1520. X#if AUSAM
  1521. X                pe.pw_strings[LNAME],
  1522. X#else
  1523. X                pp->pw_name,
  1524. X#endif
  1525. X            "@", systemid, ".", MYDOMAIN);
  1526. X        if (CMP(mname, h.h_from) != 0)
  1527. X            error("Can't cancel articles you didn't write.");
  1528. X        free(mname);
  1529. X    }
  1530. X    if (unlink(fname) != 0)
  1531. X        error("Couldn't unlink %s", fname);
  1532. X
  1533. X}
  1534. END_OF_FILE
  1535. if test 3647 -ne `wc -c <'rna/history.c'`; then
  1536.     echo shar: \"'rna/history.c'\" unpacked with wrong size!
  1537. fi
  1538. # end of 'rna/history.c'
  1539. fi
  1540. if test -f 'rnews/README' -a "${1}" != "-c" ; then 
  1541.   echo shar: Will not clobber existing file \"'rnews/README'\"
  1542. else
  1543. echo shar: Extracting \"'rnews/README'\" \(3793 characters\)
  1544. sed "s/^X//" >'rnews/README' <<'END_OF_FILE'
  1545. XThis is an alpha test release.  Do not distribute modified copies of it;
  1546. Xsee the COPYRIGHT file for details.
  1547. X
  1548. XSend bug reports to utzoo!cnews-alpha.  This software is believed to
  1549. Xwork, though it could doubtless stand some improvement.  The code is
  1550. Xgoing to be cleaned up and possibly sped up before general release.
  1551. X
  1552. X
  1553. X``yer about to be boarded, ye scurvy network news dogs! har har ...''
  1554. X        -- Oliver Wendell Jones, Bloom County Hacker & Cracker
  1555. X
  1556. X``No news is good news.''
  1557. X``When bigger machines are built, netnews will saturate them.''
  1558. X``USENET -- All the news that's fit to `N'.''
  1559. X        -- /usr/games/fortune
  1560. X
  1561. X``B news is Bad news.''
  1562. X``Net news is the television of computing.''
  1563. X        -- Geoff Collyer
  1564. X
  1565. XDoes your inews wallow in the mud like a pregnant sow? Does your expire
  1566. Xflop on its back, wiggle its feet and gurgle pathetically?  Then you
  1567. Xneed new, improved *C news*, the sentient being's news system: no more
  1568. Xodious Relay-Version headers, no more sluggish machines caused by
  1569. Xoverfed news software.  Real locking.  No line-eater bugs.
  1570. X
  1571. XAvailable from fine news administrators everywhere.  C news.
  1572. X___
  1573. X
  1574. XAssumptions:
  1575. X    you already have B news and possibly rn running
  1576. X    you personally installed B news
  1577. X    you are now upgrading to C news
  1578. X
  1579. XBefore using make for anything else, you must
  1580. X
  1581. X    make variant
  1582. X
  1583. Xwhere variant is your UNIX variant: v7, v8, v9, bsd42 or usg.
  1584. XIt will tell you to edit the makefile DEPSRC and DEPOBJ definitions to match.
  1585. X
  1586. XIf you need a roadmap, see ../usr.lib/README.
  1587. X
  1588. X../expire and ../time require that /usr/include/time.h exists.
  1589. XIf it doesn't exist on your (4.2BSD) system, thanks to gratuitous
  1590. Xtinkering (at UCB), execute
  1591. X
  1592. X    cd /usr/include; ln -s sys/time.h
  1593. X
  1594. XThis may require super-user privileges, which should be easy to obtain
  1595. Xon 4.2.
  1596. X
  1597. XAfter compiling inews, install it as /usr/lib/news/realinews,
  1598. Xsetuid-news.  On older systems, you will to also install a small
  1599. Xprogram, setnewids, setuid-root.  If this worries you, read
  1600. Xsetnewsids.c; all it does is execute setgid(), setuid() to the "news"
  1601. Xgroup and user if they exist, otherwise realinews's real ids. Install
  1602. Xsh/inews as /usr/bin/inews, rnews.sh as /usr/bin/rnews and
  1603. X/usr/bin/cunbatch.  You can test realinews by giving NEWSCTL, NEWSBIN
  1604. Xor NEWSARTS environment variables to change the library, binary or
  1605. Xspool directories and I encourage this.
  1606. X
  1607. XIf you plan to run rn, you'll need the latest rn patches to allow Xref:
  1608. Xto work without Relay-Version:.
  1609. X
  1610. XYou can get postnews from B news & Pnews from rn.
  1611. X
  1612. XYour sys file should not refer to a given batch file (with the F or f
  1613. Xflags) more than once, or the batch file will be scrambled; this will be
  1614. Xfixed and isn't a disaster as the C batcher is quite flexible and can
  1615. Xcompensate.  The Ln flag isn't yet fully implemented.
  1616. X
  1617. XIf your `domain' isn't "uucp", you will need to put your domain name in
  1618. X/usr/lib/news/domain.  No upper case letters in your new domain please,
  1619. Xthere is no call for it and it just looks ugly.
  1620. X
  1621. XYou must remove /usr/lib/news/LOCK* and /usr/lib/news/lock.* somewhere
  1622. Xin /etc/rc*.  Thus you must only permit rnews to run on file servers.
  1623. X
  1624. XYou'll need compress for compressing or uncompressing batches of news.
  1625. XSee the contact person of your news feed or the moderator of the
  1626. Xnewsgroup comp.sources.unix.
  1627. X
  1628. XSee the anews directory for conversion filters from A to B and back.
  1629. X
  1630. XYou'll need to install /usr/lib/news/gngp (see ../gngp) before inews
  1631. Xwill work.
  1632. X
  1633. XB-2.11-isms: your /usr/lib/news/mailpaths file must be updated to point
  1634. Xat your nearest backbone site.  A 5th sys file field for Distribution:
  1635. Xpatterns is here (add them in sys after the subscription list, separated
  1636. Xby "/"), and a 6th field for excluded hosts is half-here, separated by
  1637. X"/" from the system name.  Active file support for 4 fields and the m
  1638. Xflag are here.
  1639. X
  1640. XGood Luck.
  1641. X
  1642. X    Geoff Collyer
  1643. END_OF_FILE
  1644. if test 3793 -ne `wc -c <'rnews/README'`; then
  1645.     echo shar: \"'rnews/README'\" unpacked with wrong size!
  1646. fi
  1647. # end of 'rnews/README'
  1648. fi
  1649. if test -f 'rnews/active.c' -a "${1}" != "-c" ; then 
  1650.   echo shar: Will not clobber existing file \"'rnews/active.c'\"
  1651. else
  1652. echo shar: Extracting \"'rnews/active.c'\" \(3462 characters\)
  1653. sed "s/^X//" >'rnews/active.c' <<'END_OF_FILE'
  1654. X/*
  1655. X * active file access functions (in-memory version)
  1656. X */
  1657. X
  1658. X#include <stdio.h>
  1659. X#include <sys/types.h>
  1660. X#include <sys/stat.h>
  1661. X#include "active.h"
  1662. X#include "news.h"
  1663. X#include "newspaths.h"
  1664. X
  1665. X#define MAXNGS 2000
  1666. X
  1667. Xstatic FILE *fp = NULL;
  1668. Xstatic char filerelname[] = "active";
  1669. Xstatic char *active = NULL;    /* points at entire active file */
  1670. Xstatic int actsize;        /* bytes in active: type int determined by fread */
  1671. Xstatic unsigned artlines;    /* lines in artlnps actually used */
  1672. X/* TODO: make this a linked list or realloc to avoid the MAXNGS limit */
  1673. Xstatic char *artlnps[MAXNGS];    /* point at lines in active file */
  1674. X
  1675. Xlong
  1676. Xincartnum(ng, inc)
  1677. Xchar *ng;
  1678. Xint inc;
  1679. X{
  1680. X    register int nglen = strlen(ng);
  1681. X    register char *pos;
  1682. X    register unsigned line = 0;
  1683. X    register long nextart = -1;
  1684. X    char artnumstr[ARTNUMWIDTH + 1];
  1685. X    extern char ldzeropad[];
  1686. X
  1687. X    if (artload() != ST_OKAY)
  1688. X        return nextart;
  1689. X    while (pos = artlnps[line], line++ < artlines && pos[0] != '\0')
  1690. X        if (STREQN(pos, ng, nglen) && pos[nglen] == ' ') {
  1691. X            nextart = atol(&pos[nglen + 1]) + inc;
  1692. X            (void) sprintf(artnumstr, ldzeropad,
  1693. X                ARTNUMWIDTH, ARTNUMWIDTH, nextart);
  1694. X            (void) strncpy(&pos[nglen + 1], artnumstr, ARTNUMWIDTH);
  1695. X            break;
  1696. X        }
  1697. X    return nextart;
  1698. X}
  1699. X
  1700. Xint
  1701. Xartload()                /* reload any cached data */
  1702. X{
  1703. X    int status = 0;
  1704. X
  1705. X    if (fp == NULL)
  1706. X        if ((fp = fopenwclex(libfile(filerelname), "r+")) == NULL)
  1707. X            status |= ST_DROPPED;
  1708. X    if (fp != NULL && active == NULL) {    /* file open, no cache */
  1709. X        struct stat sb;
  1710. X
  1711. X        if (fstat(fileno(fp), &sb) < 0)
  1712. X            warning("can't fstat %s", libfile(filerelname));
  1713. X        else if (actsize = sb.st_size, /* squeeze into an int */
  1714. X            (unsigned)actsize != sb.st_size)
  1715. X            warning("%s won't fit into memory", libfile(filerelname));
  1716. X        else if ((active = malloc((unsigned)actsize+1)) == NULL)
  1717. X            warning("can't allocate memory for %s", libfile(filerelname));
  1718. X        else {
  1719. X            rewind(fp);
  1720. X            /* TODO: read with fgets to avoid linescan() */
  1721. X            if (fread(active, 1, actsize, fp) != actsize) {
  1722. X                warning("error reading %s", libfile(filerelname));
  1723. X                free(active);
  1724. X                active = NULL;
  1725. X            } else {
  1726. X                active[actsize] = '\0';    /* make a proper string */
  1727. X                if ((artlines = linescan(active, artlnps,
  1728. X                    MAXNGS)) >= MAXNGS) {
  1729. X                        extern char *progname;
  1730. X
  1731. X                    (void) fprintf(stderr,
  1732. X                        "%s: too many newsgroups in %s\n",
  1733. X                        progname, libfile(filerelname));
  1734. X                    free(active);
  1735. X                    active = NULL;
  1736. X                }
  1737. X            }
  1738. X        }
  1739. X        if (active == NULL)
  1740. X            status |= ST_DROPPED;    /* give up! */
  1741. X    }
  1742. X    return status;
  1743. X}
  1744. X
  1745. Xint
  1746. Xartsync()                /* sync to disk any cached data */
  1747. X{
  1748. X    int status = 0;
  1749. X
  1750. X    if (fp != NULL) {
  1751. X        rewind(fp);
  1752. X        if (active != NULL && fwrite(active, actsize, 1, fp) != 1 ||
  1753. X            fclose(fp) == EOF) {
  1754. X            warning("error writing %s", libfile(filerelname));
  1755. X            status |= ST_DROPPED;
  1756. X        }
  1757. X    }
  1758. X    fp = NULL;
  1759. X    if (active != NULL)
  1760. X        free(active);        /* give back memory active used */
  1761. X    active = NULL;
  1762. X    return status;
  1763. X}
  1764. X
  1765. X/*
  1766. X * Store in lnarray the addresses of the starts of lines in s.
  1767. X * Return the number of lines found; if greater than nent,
  1768. X * store only nent and return nent.
  1769. X */
  1770. Xint
  1771. Xlinescan(s, lnarray, nent)
  1772. Xregister char *s;
  1773. Xregister char **lnarray;
  1774. Xregister int nent;
  1775. X{
  1776. X    register int i = 0;
  1777. X    register char *nlp = s;
  1778. X
  1779. X    if (i < nent)
  1780. X        lnarray[i++] = s;
  1781. X    while (i < nent && (nlp = index(nlp, '\n')) != NULL)
  1782. X        lnarray[i++] = ++nlp;
  1783. X    return i;
  1784. X}
  1785. X
  1786. X/* ARGSUSED hdrs */
  1787. Xmoderated(hdrs)
  1788. Xstruct headers *hdrs;
  1789. X{
  1790. X    /* TODO: look at 4th field of active file; needs new active.c hook */
  1791. X    return NO;            /* stub */
  1792. X}
  1793. END_OF_FILE
  1794. if test 3462 -ne `wc -c <'rnews/active.c'`; then
  1795.     echo shar: \"'rnews/active.c'\" unpacked with wrong size!
  1796. fi
  1797. # end of 'rnews/active.c'
  1798. fi
  1799. if test -f 'rnews/makefile' -a "${1}" != "-c" ; then 
  1800.   echo shar: Will not clobber existing file \"'rnews/makefile'\"
  1801. else
  1802. echo shar: Extracting \"'rnews/makefile'\" \(3080 characters\)
  1803. sed "s/^X//" >'rnews/makefile' <<'END_OF_FILE'
  1804. X# makefile for C news relaynews
  1805. X
  1806. X# define NOSTOREVAL if your dbm store() returns no value (as in orig. v7)
  1807. X# -I. for fcntl.h if present
  1808. XDEFINES= -I../include -I. -DSTATIC=
  1809. X# -Dvoid=int            # if your compiler doesn't understand void's
  1810. X# -DMAXLONG=017777777777L    # if your compiler lacks "unsigned long" type
  1811. X# -Dindex=strchr -Drindex=strrchr    # if not on (System III or V or PWB)
  1812. X
  1813. XCFLAGS=-O -f68881 $(DEFINES) # -pg # -Z: John Bruner's Z0MAGIC (unmapped first page)
  1814. XLIBS= -ldbm # -lstdio
  1815. XLLIBS=-llocal
  1816. XPROPTS=-l132
  1817. XP=impr -p
  1818. X
  1819. XPOSSDEPFILES=fcntl.h gethostname.c getwd.c dbm.c mkdir.c ftime.c clsexec.c memcpy.c
  1820. X# adjust next three lines for your OS; sources are links to vers/*/*.c
  1821. XDEPHDR=
  1822. XDEPSRC= clsexec.c memcpy.c zeropad.c
  1823. XDEPOBJ= clsexec.o memcpy.o zeropad.o
  1824. X
  1825. XLIBSRCS= ../libcnews/*.c
  1826. XLIBOBJS= ../libcnews/libcnews.a ../libc/libc.a
  1827. XSRC=relaynews.c active.c caches.c checkdir.c control.c fileart.c \
  1828. X    headers.c history.c hostname.c io.c msgs.c procart.c \
  1829. X    string.c sys.c transmit.c $(DEPSRC) $(LIBSRCS)
  1830. XOBJ=relaynews.o active.o caches.o checkdir.o control.o fileart.o \
  1831. X    headers.o history.o hostname.o io.o msgs.o procart.o \
  1832. X    string.o sys.o transmit.o $(DEPOBJ) $(LIBOBJS)
  1833. XFILES=$(NONCFILES) $(CFILES)
  1834. XNONCFILES= TODO* COPYRIGHT README ads/README ads/[0-9]* \
  1835. X    inews anne.jones tear rnews makefile
  1836. XCFILES= ../include/*.h cpu.h headers.h system.h $(DEPHDR) $(SRC)
  1837. XLINT=lint
  1838. XLINTFLAGS=-haz $(DEFINES)
  1839. X
  1840. Xrelaynews: $(OBJ) ../libcnews/*.c
  1841. X    (cd ../libcnews; make)
  1842. X    $(CC) $(CFLAGS) $(OBJ) $(LIBS) -o $@
  1843. Xlint: $(SRC)
  1844. X    $(LINT) $(LINTFLAGS) $(SRC) $(LIBS) $(LLIBS) | egrep -v ':$$'
  1845. Xlintport: $(SRC)
  1846. X    $(LINT) $(LINTFLAGS) -p $(SRC) $(LIBS) $(LLIBS)
  1847. X
  1848. XTODO.grep: TODO
  1849. X    -egrep TODO TODO ../include/*.h *.h *.c sh/* >$@
  1850. X    -egrep TODO ../libc/memcpy.fast/src/*.c ../libcnews/*.c >>$@
  1851. X
  1852. Xv7 v8 v9 usg bsd42: clean
  1853. X    for file in vers/$@/*.c; do ln $$file; done
  1854. X    @echo 'Now edit makefile DEPSRC and DEPOBJ definitions to match:'
  1855. X    @echo vers/$@/*.c | sed 's;vers/$@/;;g'
  1856. X
  1857. Xprint: printc printnonc
  1858. X    touch $@
  1859. Xprintc: $(CFILES)
  1860. X    /usr/bin/pp -T300 -fR $? | dimp -t | impr
  1861. X    touch $@
  1862. Xprintnonc: $(NONCFILES)
  1863. X    pr $(PROPTS) $? | $P
  1864. X    touch $@
  1865. Xdistr: $(FILES)
  1866. X    (echo relaynews update of `date`; echo ""; bundle $?) | /bin/mail cnews-updates
  1867. X    touch $@
  1868. Xclean:
  1869. X    rm -f core a.out relaynews *.o $(POSSDEPFILES)
  1870. X
  1871. X# header dependencies follow
  1872. Xactive.o:    active.h ../include/news.h ../include/newspaths.h
  1873. Xcaches.o:    ../include/news.h
  1874. Xcheckdir.o:    ../include/news.h
  1875. Xcontrol.o:    ../include/news.h ../include/newspaths.h headers.h history.h
  1876. Xfileart.o:    ../include/news.h ../include/newspaths.h active.h headers.h system.h
  1877. Xheaders.o:    ../include/news.h headers.h
  1878. Xhistory.o:    ../include/news.h ../include/newspaths.h headers.h
  1879. Xhostname.o:    ../include/news.h ../include/newspaths.h
  1880. Xio.o:        ../include/news.h
  1881. Xmsgs.o:        ../include/news.h
  1882. Xprocart.o:    ../include/news.h active.h headers.h system.h
  1883. Xrelaynews.o:    ../include/news.h ../include/newspaths.h active.h cpu.h headers.h system.h
  1884. Xstring.o:    ../include/news.h
  1885. Xsys.o:        ../include/news.h ../include/newspaths.h system.h
  1886. Xtransmit.o:    ../include/news.h ../include/newspaths.h headers.h system.h
  1887. END_OF_FILE
  1888. if test 3080 -ne `wc -c <'rnews/makefile'`; then
  1889.     echo shar: \"'rnews/makefile'\" unpacked with wrong size!
  1890. fi
  1891. # end of 'rnews/makefile'
  1892. fi
  1893. if test -f 'rnews/speed/mem/active.c' -a "${1}" != "-c" ; then 
  1894.   echo shar: Will not clobber existing file \"'rnews/speed/mem/active.c'\"
  1895. else
  1896. echo shar: Extracting \"'rnews/speed/mem/active.c'\" \(3682 characters\)
  1897. sed "s/^X//" >'rnews/speed/mem/active.c' <<'END_OF_FILE'
  1898. X/*
  1899. X * active file access functions (in-memory version)
  1900. X *    TODO: use hashing for speed & to eliminate MAXNGS
  1901. X */
  1902. X
  1903. X#include <stdio.h>
  1904. X#include <sys/types.h>
  1905. X#include <sys/stat.h>
  1906. X#include "news.h"
  1907. X
  1908. X#define MAXNGS 2000
  1909. X
  1910. Xstatic FILE *fp = NULL;
  1911. Xstatic char filerelname[] = "active";
  1912. Xstatic char *active = NULL;    /* points at entire active file */
  1913. Xstatic int actsize;        /* bytes in active: type int determined by fread */
  1914. Xstatic unsigned artlines;    /* lines in artlnps actually used */
  1915. X/* TODO: make this a linked list to avoid the MAXNGS limit? */
  1916. Xstatic char *artlnps[MAXNGS];    /* point at lines in active file */
  1917. X
  1918. X/* TODO: make these two macros in a header file? */
  1919. Xlong
  1920. Xnxtartnum(ng)
  1921. Xchar *ng;
  1922. X{
  1923. X    long incartnum();
  1924. X
  1925. X    return incartnum(ng, 1);
  1926. X}
  1927. X
  1928. Xlong
  1929. Xprevartnum(ng)
  1930. Xchar *ng;
  1931. X{
  1932. X    long incartnum();
  1933. X
  1934. X    return incartnum(ng, -1);
  1935. X}
  1936. X
  1937. Xstatic long
  1938. Xincartnum(ng, inc)
  1939. Xchar *ng;
  1940. Xint inc;
  1941. X{
  1942. X    register int nglen = strlen(ng);
  1943. X    register char *pos;
  1944. X    register unsigned line = 0;
  1945. X    register long nextart = -1;
  1946. X    char artnumstr[ARTNUMWIDTH + 1];
  1947. X    extern char ldzeropad[];
  1948. X    char *sprintf(), *strncpy();
  1949. X    long atol();
  1950. X
  1951. X    if (artload() != ST_OKAY)
  1952. X        return nextart;
  1953. X    while (pos = artlnps[line], line++ < artlines && pos[0] != '\0')
  1954. X        if (STREQN(pos, ng, nglen) && pos[nglen] == ' ') {
  1955. X            nextart = atol(&pos[nglen + 1]) + inc;
  1956. X            (void) sprintf(artnumstr, ldzeropad,
  1957. X                ARTNUMWIDTH, ARTNUMWIDTH, nextart);
  1958. X            (void) strncpy(&pos[nglen + 1], artnumstr, ARTNUMWIDTH);
  1959. X            break;
  1960. X        }
  1961. X    return nextart;
  1962. X}
  1963. X
  1964. Xint
  1965. Xartload()                /* reload any cached data */
  1966. X{
  1967. X    int status = 0;
  1968. X    char *libfile();
  1969. X    FILE *fopenwclex();
  1970. X
  1971. X    if (fp == NULL)
  1972. X        if ((fp = fopenwclex(libfile(filerelname), "r+")) == NULL)
  1973. X            status |= ST_DROPPED;
  1974. X    if (fp != NULL && active == NULL) {    /* file open, no cache */
  1975. X        struct stat sb;
  1976. X        char *malloc();
  1977. X
  1978. X        if (fstat(fileno(fp), &sb) < 0)
  1979. X            warning("can't fstat %s", libfile(filerelname));
  1980. X        else if (actsize = sb.st_size, /* squeeze into an int */
  1981. X            (unsigned)actsize != sb.st_size)
  1982. X            warning("%s won't fit into memory", libfile(filerelname));
  1983. X        else if ((active = malloc((unsigned)actsize+1)) == NULL)
  1984. X            warning("can't allocate memory for %s", libfile(filerelname));
  1985. X        else {
  1986. X            rewind(fp);
  1987. X            /* TODO: read with fgets to avoid linescan() */
  1988. X            if (fread(active, 1, actsize, fp) != actsize) {
  1989. X                warning("error reading %s", libfile(filerelname));
  1990. X                free(active);
  1991. X                active = NULL;
  1992. X            } else {
  1993. X                active[actsize] = '\0';    /* make a proper string */
  1994. X                if ((artlines = linescan(active, artlnps,
  1995. X                    MAXNGS)) >= MAXNGS) {
  1996. X                        extern char *progname;
  1997. X
  1998. X                    (void) fprintf(stderr,
  1999. X                        "%s: too many newsgroups in %s\n",
  2000. X                        progname, libfile(filerelname));
  2001. X                    free(active);
  2002. X                    active = NULL;
  2003. X                }
  2004. X            }
  2005. X        }
  2006. X        if (active == NULL)
  2007. X            status |= ST_DROPPED;    /* give up! */
  2008. X    }
  2009. X    return status;
  2010. X}
  2011. X
  2012. Xint
  2013. Xartsync()                /* sync to disk any cached data */
  2014. X{
  2015. X    int status = 0;
  2016. X    char *libfile();
  2017. X
  2018. X    if (fp != NULL) {
  2019. X        rewind(fp);
  2020. X        if (active != NULL && fwrite(active, actsize, 1, fp) != 1) {
  2021. X            warning("error writing %s", libfile(filerelname));
  2022. X            status |= ST_DROPPED;
  2023. X        }
  2024. X        if (fclose(fp) == EOF)
  2025. X            status |= ST_DROPPED;
  2026. X    }
  2027. X    fp = NULL;
  2028. X    if (active != NULL)
  2029. X        free(active);        /* give back memory active used */
  2030. X    active = NULL;
  2031. X    return status;
  2032. X}
  2033. X
  2034. X/*
  2035. X * Store in lnarray the addresses of the starts of lines in s.
  2036. X * Return the number of lines found; if greater than nent,
  2037. X * store only nent and return nent.
  2038. X */
  2039. Xint
  2040. Xlinescan(s, lnarray, nent)
  2041. Xregister char *s;
  2042. Xregister char **lnarray;
  2043. Xregister int nent;
  2044. X{
  2045. X    register int i = 0;
  2046. X    register char *nlp = s;
  2047. X    char *index();
  2048. X
  2049. X    if (i < nent)
  2050. X        lnarray[i++] = s;
  2051. X    while (i < nent && (nlp = index(nlp, '\n')) != NULL)
  2052. X        lnarray[i++] = ++nlp;
  2053. X    return i;
  2054. X}
  2055. END_OF_FILE
  2056. if test 3682 -ne `wc -c <'rnews/speed/mem/active.c'`; then
  2057.     echo shar: \"'rnews/speed/mem/active.c'\" unpacked with wrong size!
  2058. fi
  2059. # end of 'rnews/speed/mem/active.c'
  2060. fi
  2061. if test -f 'rnews/speed/mem/sys.c' -a "${1}" != "-c" ; then 
  2062.   echo shar: Will not clobber existing file \"'rnews/speed/mem/sys.c'\"
  2063. else
  2064. echo shar: Extracting \"'rnews/speed/mem/sys.c'\" \(4014 characters\)
  2065. sed "s/^X//" >'rnews/speed/mem/sys.c' <<'END_OF_FILE'
  2066. X/*
  2067. X * inews sys file reading functions (in-memory version)
  2068. X */
  2069. X
  2070. X#include <stdio.h>
  2071. X#include <sys/types.h>
  2072. X#include <sys/stat.h>
  2073. X#include "news.h"
  2074. X#include "system.h"
  2075. X
  2076. Xstatic FILE *fp = NULL;        /* descriptor for libfile("sys") */
  2077. Xstatic char filerelname[] = "sys";
  2078. Xstatic char defaultcmd[] = "exit 1";    /* reminder to bozo admins */
  2079. Xstatic struct system *firstsys = NULL;    /* cache */
  2080. Xstatic struct system *currsys = NULL;    /* current system */
  2081. X
  2082. Xstruct system *
  2083. Xoursys()            /* return our sys entry */
  2084. X{
  2085. X    register struct system *sys;
  2086. X    static struct system fakesys;
  2087. X    char *hostname();
  2088. X    struct system *nextsys();
  2089. X
  2090. X    rewsys();
  2091. X    while ((sys = nextsys()) != NULL && !STREQ(sys->sy_name, hostname()))
  2092. X        ;
  2093. X    if (sys == NULL) {        /* no entry; cook one up */
  2094. X        fakesys.sy_name = hostname();
  2095. X        fakesys.sy_ngs = "all";
  2096. X        fakesys.sy_flags = 0;
  2097. X        fakesys.sy_lochops = 0;
  2098. X        fakesys.sy_cmd = defaultcmd;
  2099. X        fakesys.sy_next = NULL;
  2100. X        sys = &fakesys;
  2101. X    }
  2102. X    return sys;
  2103. X}
  2104. X
  2105. X/*
  2106. X * Returned pointer points at a static struct whose members
  2107. X * point at static storage.
  2108. X */
  2109. Xstruct system *
  2110. Xnextsys()                /* return next sys entry */
  2111. X{
  2112. X    struct system *retsys;
  2113. X    char *libfile();
  2114. X    FILE *fopenwclex();
  2115. X
  2116. X    if (firstsys == NULL && fp == NULL)
  2117. X        if ((fp = fopenwclex(libfile(filerelname), "r")) == NULL)
  2118. X            return NULL;
  2119. X    if (fp != NULL && firstsys == NULL)    /* file open, no cache */
  2120. X        readsys();            /* read & parse fp */
  2121. X    retsys = currsys;            /* save current ptr. */
  2122. X    if (currsys != NULL)
  2123. X        currsys = currsys->sy_next;    /* advance current ptr. */
  2124. X    return retsys;
  2125. X}
  2126. X
  2127. Xrewsys()
  2128. X{
  2129. X    currsys = firstsys;
  2130. X}
  2131. X
  2132. Xstatic char *curr, *next;            /* parsing state */
  2133. X
  2134. Xstatic
  2135. Xreadsys()
  2136. X{
  2137. X    char sysline[MAXLINE];
  2138. X
  2139. X    rewind(fp);
  2140. X    /* TODO: write & use cfgets to read continued lines (need bigger MAXLINE) */
  2141. X    while (fgets(sysline, sizeof sysline, fp) != NULL)
  2142. X        if (sysline[0] != '#' && sysline[0] != '\n') {    /* not a comment */
  2143. X            register struct system *sysp;
  2144. X            char *flagstring;
  2145. X            char *malloc();
  2146. X
  2147. X            sysp = (struct system *)malloc(sizeof *sysp);
  2148. X            if (sysp == NULL)
  2149. X                errunlock("out of memory for system structs", "");
  2150. X
  2151. X            /* parse into sysp */
  2152. X            trim(sysline);
  2153. X            next = sysline;
  2154. X            parse(&sysp->sy_name);
  2155. X            parse(&sysp->sy_ngs);
  2156. X            parse(&flagstring);
  2157. X            parse(&sysp->sy_cmd);
  2158. X            /* could check for extra fields here */
  2159. X            sysp->sy_flags = flgtobits(flagstring);
  2160. X            sysp->sy_lochops = 0;        /* Ln value someday */
  2161. X            free(flagstring);        /* malloced by parse */
  2162. X            sysp->sy_next = NULL;
  2163. X
  2164. X            /* fill in any defaults */
  2165. X            if (sysp->sy_cmd[0] == '\0') {
  2166. X                free(sysp->sy_cmd);    /* malloced by parse */
  2167. X                sysp->sy_cmd = defaultcmd;    /* NB not malloced */
  2168. X            }
  2169. X
  2170. X            /* stash *sysp away on the tail of the current list */
  2171. X            if (firstsys == NULL)
  2172. X                firstsys = sysp;        /* 1st system */
  2173. X            else
  2174. X                currsys->sy_next = sysp;    /* tack on tail */
  2175. X            currsys = sysp;
  2176. X        }
  2177. X    (void) fclose(fp);        /* file no longer needed */
  2178. X    fp = NULL;            /* mark file closed */
  2179. X    rewsys();
  2180. X}
  2181. X
  2182. Xparse(into)
  2183. Xregister char **into;
  2184. X{
  2185. X    char *strsave(), *parsecolon();
  2186. X
  2187. X    curr = next;
  2188. X    if (curr == NULL)
  2189. X        *into = strsave("");
  2190. X    else {
  2191. X        next = parsecolon(curr);
  2192. X        *into = strsave(curr);
  2193. X    }
  2194. X    if (*into == NULL)
  2195. X        errunlock("out of memory for sys strings", "");
  2196. X}
  2197. X
  2198. Xchar *
  2199. Xparsecolon(line)        /* return NULL or ptr. to byte after colon */
  2200. Xchar *line;
  2201. X{
  2202. X    register char *colon;
  2203. X
  2204. X    INDEX(line, ':', colon);
  2205. X    if (colon != NULL)
  2206. X        *colon++ = '\0';    /* turn colon into a NUL */
  2207. X    return colon;
  2208. X}
  2209. X
  2210. Xstatic int
  2211. Xflgtobits(s)
  2212. Xregister char *s;
  2213. X{
  2214. X    register int bits = 0;
  2215. X
  2216. X    for (; *s != '\0'; s++)
  2217. X        switch (*s) {
  2218. X        case 'A':
  2219. X            errunlock("A news format not supported", "");
  2220. X            /* NOTREACHED */
  2221. X        case 'B':                /* mostly harmless */
  2222. X            break;
  2223. X        case 'F':
  2224. X            bits |= FLG_BATCH;
  2225. X            break;
  2226. X        case 'L':
  2227. X            bits |= FLG_LOCAL;
  2228. X            /* TODO: parse Ln, but maybe not here */
  2229. X            break;
  2230. X        case 'N':
  2231. X            bits |= FLG_IHAVE;
  2232. X            errunlock("N flag given but I-have/send-me is not supported", "");
  2233. X            /* NOTREACHED */
  2234. X        case 'U':
  2235. X            bits |= FLG_PERM;
  2236. X            break;
  2237. X        default:
  2238. X            errunlock("unknown sys flag `%s' given", s);
  2239. X            /* NOTREACHED */
  2240. X        }
  2241. X    return bits;
  2242. X}
  2243. END_OF_FILE
  2244. if test 4014 -ne `wc -c <'rnews/speed/mem/sys.c'`; then
  2245.     echo shar: \"'rnews/speed/mem/sys.c'\" unpacked with wrong size!
  2246. fi
  2247. # end of 'rnews/speed/mem/sys.c'
  2248. fi
  2249. echo shar: End of archive 6 \(of 14\).
  2250. ##  End of shell archive.
  2251. exit 0
  2252.